<template>
  对象的基类：初始值是函数的情况，$react() 支持多层，响应性支持两层。
  <el-switch v-model="isLog"
    active-text="记日志"
    inactive-text="不记了"></el-switch>
  <br>
  <el-row>
    <el-col :span="2">
      <el-button @click="change1" > 测试 $patch</el-button>
      <br><br> 
      <el-button @click="setValue" > 测试 $state </el-button>
      <br><br> 
      <el-button @click="reset" >重置</el-button>
    </el-col>
    <el-col :span="2">
      <el-button @click="nfStateRet2.$state={name: '模板赋值'}" >模板 $state</el-button>
      <br><br> 
      <el-button @click="nfStateRet2.$patch({name: '模板改'})" >模板 $patch</el-button>
      <br><br> 
      <el-button @click="nfStateRet2.$reset()" >模板 $reset</el-button>
    </el-col>
  </el-row>
  <hr>
  单层对象：<br>
  nfStateRet：
  <show-object :obj="nfStateRet" v-if="true"></show-object>

  <hr>
  多层对象： <br> 
  nfStateRet2：
  <show-object :obj="nfStateRet2" v-if="true"></show-object>
  <hr>
  <show-log :state="nfStateRet2"></show-log>
</template>

<script lang="ts">
  import { defineComponent, reactive, watch, ref, watchEffect  } from 'vue'

  import {
    BaseObject
  } from '../../../lib/main'

  // 显示日志
  import showLog from '../state-log/log-table.vue'
  // 显示对象
  import showObject from '../state-log/show-object.vue'

  type State1 = {
    name: string,
    age: number,
    arr: Array<number>
  }

  
  type State2 = {
    name: string,
    age: number,
    info: {
      org: string,
      other: {
        name: string
      }
    }
  }
  /**
   * 基础操作：reset、state、patch
   * * 初始值：对象、函数
   * * 结构：单层、多层
   */
  export default defineComponent({
    name: 'nf-state-base-object-function',
    components: {
      showLog,
      showObject
    },
    props: {
   
    },
    setup(props, context) {

      const isLog = ref(false)

      // 单层对象
      const nfState = new BaseObject<State1>(() => {
        return {
          name: '单层对象',
          age: 20,
          arr: [1,2,3]
        }
      })

      // 多层对象，不转换
      const nfState2 = new BaseObject<State2>(() => {
        return {
          name: '多层对象，子属性不支持react',
          age: 11,
          info: {
            org: '部门一',
            other: {
              name: '第三层'
            }
          }
        }
      }, '测试日志', isLog.value)
      
      const nfStateRet  = reactive(nfState)
      const nfStateRet2 = reactive(nfState2)
      console.log('nfState', nfState)
      console.log('nfStateRet', nfStateRet)
      console.log('nfState2', nfState2)
      console.log('nfStateRet2', nfStateRet2)
      console.log('toRaw', nfStateRet2.$toRaw())

      for (const key in nfState) {
        console.log(key)
      }
      console.log('nfState —— keys:', Object.keys(nfState))
  
      watch(nfStateRet.arr, (val1, val2) => {
        // console.log('watch -- arr ：', val1, val2)
      })

      watch(nfStateRet2.info.other, (val1, val2) => {
        // console.log('watch -- other 3 ：', val1, val2)
      })

      watchEffect(() => {
        // 改动是否记录日志
        nfState2.$isLog = isLog.value
      })

      const change1 = () => {
        // nfStateRet.arr = [3,2,1]
        nfStateRet.$patch({
          name: 'patch 修改：' + new Date().valueOf().toString(),
          aaa: 1,
          arr: [2,3,4]
        })
        nfStateRet2.$patch({
          name: 'patch 修改：' + new Date().valueOf().toString(),
          aaa: 1,
          info: {
            org: 'patch 改部门' + new Date().valueOf().toString(),
            other: {
              name: '第三层' + new Date().valueOf().toString()
            }
          }
        })
      }

      const setValue = () => {
        nfStateRet.$state = {
          name: 'state 修改：' + new Date().valueOf().toString(),
          age: 66,
          arr: [1,2,3]
        }
        
        nfStateRet2.$state = {
          name: new Date().valueOf().toString(),
          age: 66,
          info: {
            org: '部门一666',
            other: {
              name: '第三层999'
            }
          } 
        }
         
      }

      const reset = () => {
        nfStateRet.$reset()
        nfStateRet2.$reset()
      }

      return {
        isLog,
        nfState,
        nfState2,
        nfStateRet,
        nfStateRet2,
        
        // 基础
        change1,
        reset,
        setValue
      }
    }
  })
</script>